﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Xml.Serialization;
using System.Text.RegularExpressions;
using System.ComponentModel;

namespace Nizm0.QOT.Library.Objects
{
    [Serializable]
    [XmlRoot("ProcedureVersion")]
    public class ProcedureVersion : System.Xml.Serialization.IXmlSerializable
    {
        //private DateTime _date = new DateTime();

        public static string Unknown = "Unknown";

        public string _originalText;
        private string _version;
        private string _hash;

        [XmlAttribute("Version")]
        public string Version
        {
            get
            {
                return _version;
            }
            set
            {
                _version = value;
            }
        }
        //[XmlAttribute("date")]
        [XmlIgnore()]
        public DateTime Date { get; set; }
        [XmlAttribute("Hash")]
        public string Hash
        {
            get { return _hash; }
            set { _hash = value; }
        }
        //[XmlAttribute("project")]
        [XmlIgnore()]
        public ExternalProject Project { get; set; }
        //[XmlAttribute("user")]
        [XmlIgnore()]
        public string User { get; set; }
        //[XmlAttribute("comment")]
        [XmlIgnore()]
        public string Comment { get; set; }
        [XmlIgnore()]
        public IProcedure Parent { get; set; }

        public ProcedureVersion()
        {
            //_version = "Unknown";
        }
        public ProcedureVersion(System.Text.RegularExpressions.Match match)
        {
            _originalText = match.Value;
            _version = match.Groups["Ver"].Value;
            Date = DateTime.Parse(match.Groups["Data"].Value);
            Project = new ExternalProject(match.Groups["Project"].Value);
            User = match.Groups["User"].Value;
            Comment = match.Groups["Comment"].Value;
        }

        public ProcedureVersion(string ver)
        {
            _version = ver;
            Date = DateTime.Now;
            Project = null;
            User = null;
            Comment = null;
        }

        public void Show()
        {
            System.Windows.Forms.Form tmpu = new System.Windows.Forms.Form();

            System.Windows.Forms.Control[] tabcontrol = new System.Windows.Forms.Control[5];
            tabcontrol[0] = new System.Windows.Forms.Label();
            tabcontrol[0].Text = this.Version;
            tabcontrol[1] = new System.Windows.Forms.Label();
            tabcontrol[1].Text = this.Date.ToString();
            tabcontrol[2] = new System.Windows.Forms.Label();
            tabcontrol[2].Text = this.Project.Project;
            tabcontrol[3] = new System.Windows.Forms.Label();
            tabcontrol[3].Text = this.User;
            tabcontrol[4] = new System.Windows.Forms.Label();
            tabcontrol[4].Size = new System.Drawing.Size(tmpu.Size.Width, tabcontrol[4].Size.Height);
            tabcontrol[4].Text = this.Comment;

            tmpu.Controls.AddRange(tabcontrol);

            System.Drawing.Point point = new System.Drawing.Point(0, 0);
            foreach (System.Windows.Forms.Control control in tmpu.Controls)
            {
                control.Location = point;
                point.Y = point.Y + control.Size.Height;
            }
            tmpu.ShowDialog();
        }

        //public virtual string Serialize()
        //{
        //    using (Stream str = new MemoryStream())
        //    {
        //        //System.Runtime.Serialization.Formatters.Binary.BinaryFormatter t = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter(
        //        System.Xml.Serialization.XmlSerializer x = new System.Xml.Serialization.XmlSerializer(typeof(ProcedureVersion));
        //        x.Serialize(str, this);
        //        using (StreamReader stmr = new StreamReader(str))
        //        {
        //            return stmr.ReadToEnd();
        //        }
        //    }
        //}

        public virtual string Serialize()
        {//dla czego się wysypuje
            //TextWriter w = new StringWriter();
            //try
            //{
            //    //System.Runtime.Serialization.Formatters.Binary.BinaryFormatter t = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter(
            //    System.Xml.Serialization.XmlSerializer x = new System.Xml.Serialization.XmlSerializer(typeof(ProcedureVersion));
            //    x.Serialize(w, this, null);
            //    w.Flush();
            //    string text = w.ToString();
            //    return text;
            //}
            //catch (Exception ex)
            //{
            //    ex.ToString();
            //}
            return string.Empty;
        }

        public virtual T Deserialize<T>(string xmlobject)
        {
            byte[] byteArray = Encoding.Unicode.GetBytes(xmlobject);
            T ip;
            using (MemoryStream stream = new MemoryStream(byteArray))
            {
                System.Xml.Serialization.XmlSerializer x = new System.Xml.Serialization.XmlSerializer(this.GetType());
                ip = (T)x.Deserialize(stream);
            }
            return ip;
        }

        /// <summary>
        /// Compare two wersion number (this and value)
        /// </summary>
        /// <param name="ver"></param>
        /// <returns>-1 if smaller, 0 if equal, 1 if greater</returns>
        public int CompareTo(ProcedureVersion ver)
        {
            char[] ch = { '.', '-', ' ' };
            string[] v1, v2;
            v1 = this.Version.Split(ch);
            v2 = ver.Version.Split(ch);

            if (v1.Length == v2.Length)
            {
                for (int i = 0; i < v1.Length; i++)
                {
                    if (v1[i] != v2[i])
                        return int.Parse(v1[i]) > int.Parse(v2[i]) ? -1 : 1;//this : ver;
                }
                return 0;//this;
            }
            else
                return v1.Length > v2.Length ? -1 : 1;//this : ver;

        }

        public override string ToString()
        {
            return string.Format("{0} - [{1}] {2}", Version, Project, Date.ToShortDateString());
        }

        #region IXmlSerializable Members

        public System.Xml.Schema.XmlSchema GetSchema()
        {
            throw new NotImplementedException();
        }

        public void ReadXml(System.Xml.XmlReader reader)
        {
            reader.MoveToContent();

            this._originalText = reader.GetAttribute("OriginalText");
            this._version = reader.GetAttribute("Version");
            this._hash = reader.GetAttribute("Hash");
            this.User = reader.GetAttribute("User");
            this.Project = new ExternalProject(reader.GetAttribute("Project"));
            this.Date = DateTime.Parse(reader.GetAttribute("Date"));
            this.Comment = reader.GetAttribute("Comment");

            Boolean isEmptyElement = reader.IsEmptyElement; // (1)
            reader.ReadStartElement();
            if (!isEmptyElement) // (1)
            {
                reader.ReadEndElement();
            }
        }

        public void WriteXml(System.Xml.XmlWriter writer)
        {
            writer.WriteAttributeString("OriginalText", _originalText);
            writer.WriteAttributeString("Version", this.Version);
            if (!string.IsNullOrWhiteSpace(this._hash))
                writer.WriteAttributeString("Hash", this._hash);
            writer.WriteAttributeString("User", this.User);
            writer.WriteAttributeString("Project", this.Project == null ? "NULL" : this.Project.Project);
            //writer.WriteAttributeString("Parent", this.Parent.Name);
            writer.WriteAttributeString("Date", this.Date.ToUniversalTime().ToString("yyyy-MM-dd"));
            writer.WriteAttributeString("Comment", this.Comment);
        }

        #endregion
    }
}
